from data_packet import DataPacket

class TrafficManager():
    """
    A class which is responsible for initializes in-memory arrays of traffic (packet) updates per tick.
    """
    def __init__(self, traffic_filename):
        """
        Constructor.
        """
        self._filename = traffic_filename
        self._number_of_nodes = None
        self._ticks = None
        self._min_packet_size = None
        self._max_packet_size = None
        self._reception_radius = None
        self._power = None
        self._queue_size = None
        self._packets = {}
        
        self._initialize()
        
    def _initialize(self):
        """
        Reads the input file and initializes the in-memory array in order to boost performance.
        """
        f = open(self._filename)
        lines = f.readlines()
        self._initialize_metadata(lines[0])
        self._initialize_packets(lines[1:])
        f.close()
        
    def _initialize_metadata(self, data_lines):
        """
        Reads the metadata line from the input file.
        """
        data = data_lines.split(",")
        self._number_of_nodes = int(data[0][data[0].index("=")+1:])
        self._ticks = int(data[1][data[1].index("=")+1:])
        self._min_packet_size = int(data[2][data[2].index("=")+1:])
        self._max_packet_size = int(data[3][data[3].index("=")+1:])
        self._reception_radius = int(data[4][data[4].index("=")+1:])
        self._power = int(data[5][data[5].index("=")+1:])
        self._queue_size = int(data[6][data[6].index("=")+1:])

    def _initialize_packets(self, lines):
        """
        Reads the traffic updates from the input file.
        """
        for line in lines:
            if line[0] == "#" or len(line.strip()) == 0:
                continue
                
            data = line.strip().split(",")
            current_tick = int(data[0][1:])
            current_packets = []
            data = data[1:]
            
            if len(data) % 4 == 0 or data[0] == '':
                # If the line is not empty (besided the current tick number)
                if len(data) >= 4:
                    for i in xrange(0, len(data), 4):
                        current_packets.append(DataPacket(int(data[i]), int(data[i+1]), int(data[i+2]), int(data[i+3])))
            else:
                raise Exception("Invalid line in traffic file: %s" % line)
                
            self._packets[current_tick] = current_packets
            
    def get_number_of_ticks(self):
        """
        Returns the number of ticks (iterations) in the simulation.
        """
        return self._ticks

    def get_number_of_nodes(self):
        """
        Returns the number of nodes in the simulation.
        """
        return self._number_of_nodes

    def get_min_packet_size(self):
        """
        Returns the minimum packet size.
        """
        return self._min_packet_size

    def get_max_packet_size(self):
        """
        Returns the maximum packet size.
        """
        return self._max_packet_size
        
    def get_reception_radius(self):
        """
        Returns the radius of the reception area.
        """
        return self._reception_radius
        
    def get_power(self):
        """
        Returns the power of the battery of each node.
        """
        return self._power
        
    def get_queue_size(self):
        """
        Returns the size of the packet queue of each node.
        """
        return self._queue_size

    def get_packets_by_tick(self, tick):
        """
        Returns all the packets of all the nodes for some tick.
        """
        return self._packets[tick]

    def get_all_packets(self):
        lst = []
        for tick_num in xrange(self._ticks):
            lst += self.get_packets_by_tick(tick_num)
        return lst